package com.ruoyi.service.card.impl;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * RSA解密工具类 - 用于解密会员码
 * 对应小程序中的 decryptData 函数
 */
public class RSADecryptUtil {

    /**
     * 从小程序前端提取的RSA私钥
     * ⚠️ 警告：私钥不应该存储在前端，这是安全漏洞
     */
    private static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC5iDQOIn1bs97f"+
            "Zv4MDvNJ7e5Wqwo7R0BeJdKWuvwR0BInEpbMV0OZRxzSmfc2/v2lQh/RBXWgVi0K"+
            "j4m5QLsfDCRVsy9nqPt6lCUZK/B/OMx58klgWT5s4IHkiB8l3u/V4VdBrqTjJpom"+
            "C2xyyCGhiol3jq/uUzogyeP85jXf37NV97M3MPofILiWTOq8rkN9xVW0TGeEI2QE"+
            "hU9ihHcx/Or7dpGrV4NxkN1QVmmhM1c3LlWYlXL3OKvvJx9GVwyOfRzg1lmsPAfs"+
            "A2AQUj88jzfZpWuN5jfVXzSI+uL/s39C0f2afDA7sbYpDNQngOETJ168R+d5zSTF"+
            "LqdF6TUzAgMBAAECggEAW/6dUSTo47+ck0mOToxbNh00QOUufZYm5If8k6DDvFFf"+
            "ruAYxdm/OxF3yTVuz2ZAfuD6xbnfSVFxo/roX2MpZYuvuI7QwqWXjIBIpOKUrYCM"+
            "YyswFwYpXfM0dQzJ5Q1V/sdtbLQcLkXFyXeAnql9g4wd/ZpSwemiuP9ifNPpgseh"+
            "Cp+qZv4a7uS/NWM3qmFD7uxMmbz5wtDIIS8oe0XIv7/PQdHcUTLr/iSNsg7oiKC6"+
            "cAN/ePtK39QXWXsp4SOzz1F+dLJuT5tETgAFgYCEe7YC1UXIpMeLUED2jS/8stN/"+
            "u9Jpqatt/31UoP3I44YmHEpKpxLUiYOK3a8UtrhUgQKBgQDeChFmYJfLwRMbWLjX"+
            "D+AdO+rN8QvDN5y+PWzKQjRDUECpom1jYXBpZzfzN69RKkLpb7bBvOgoIJglgZdF"+
            "bplvWlXG5mqrBpXbhxfbNf2/PtJVKaaEpLjLzTgFNhEJIoQNY6i9Hl5szYbhqY0H"+
            "CW5KYU99ep3Ywv3Xs6EEPis0RwKBgQDV6LIT0BpdBzW2PnEPKAIYAzTw1nZPWGrU"+
            "xwnSkAEDj/1t1Ezh4WqXEefiOrZDg1hETdlEeghEcs55t2e947vvvYCYGo4x+KNe"+
            "nRpBJ2xGizSDz9FKJvBJ8BuI9RVimiCNGmLP1I+F1W+eb/n9ATcxNU5vTMa0XiK1"+
            "jSBV+GNJtQKBgQCyIzuwekBunPlaUEUDbd4tNhv8m64HMf/T9O3qG1FYy/ME5aaD"+
            "O/J27fPKctt578D9Db5/ErLjNrs6JA0cDE6XMs9sowHjMoZaOLkgCuIIZDtVTfQl"+
            "qQ4FnCCctbLXNFTjdRg0mj/BZOcY9vGJOry8efPPROeMt2v2eUvuXn5FEwKBgHT7"+
            "ok/lklVn+P7m3SvdxG9faZeAogk4oIwnIf8OlA9fsshav4UUoxdlSnxVgZIghagt"+
            "LvIdDuJoKvUz0T9vCTvOVkJY24UGpkm6/z28kqFtxdWEVMAJ1YWKE3TuG7jl84FX"+
            "ecyRQcB+fmGWeY/dF1MJBREnWtAPX0oMmS+K/Lm1AoGBANpEPc0nh2sUNlE1P6PJ"+
            "mxVLPV0EF/iOs1smqy5mLm2e8RIV562oJBSHXu2USCBlLNhxlIW9ig2qXc9MDOsZ"+
            "TdUf+9+rSwo4h0KK/U2ZjIZKj5T11ip3yHEZR0xd02C860Es5tpGcDR1z7Qcqgg2"+
            "rSN+vP62yTP8BPve8iVb8Nmj";

    /**
     * 加密算法
     */
    private static final String ALGORITHM = "RSA";

    /**
     * RSA最大解密密文大小（2048位密钥）
     */
    private static final int MAX_DECRYPT_BLOCK = 256;

    /**
     * 解密会员码数据
     *
     * @param encryptedData 从 /v1/memberCard/code 接口获取的加密数据（Base64编码）
     * @return 解密后的明文数据
     * @throws Exception 解密失败时抛出异常
     */
    public static String decryptData(String encryptedData) throws Exception {
        // 1. 获取私钥对象
        PrivateKey privateKey = getPrivateKey(PRIVATE_KEY);

        // 2. 创建Cipher实例
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // 3. Base64解码加密数据
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);

        // 4. 分段解密（RSA加密有长度限制）
        byte[] decryptedBytes = doFinalWithBlock(cipher, encryptedBytes, MAX_DECRYPT_BLOCK);

        // 5. 转换为字符串
        return new String(decryptedBytes, "UTF-8");
    }

    /**
     * 从Base64编码的私钥字符串获取PrivateKey对象
     *
     * @param privateKeyStr Base64编码的私钥字符串（PKCS#8格式）
     * @return PrivateKey对象
     * @throws Exception 转换失败时抛出异常
     */
    private static PrivateKey getPrivateKey(String privateKeyStr) throws Exception {
        // 去除私钥中的空格、换行等字符
        String privateKeyPEM = privateKeyStr
                .replaceAll("\\s", "")
                .replace("-----BEGINPRIVATEKEY-----", "")
                .replace("-----ENDPRIVATEKEY-----", "");

        // Base64解码
        byte[] keyBytes = Base64.getDecoder().decode(privateKeyPEM);

        // 生成私钥
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 分段加密/解密
     * RSA加密对明文长度有限制，需要分段处理
     *
     * @param cipher 加密/解密器
     * @param data 待处理的数据
     * @param maxBlock 每次处理的最大字节数
     * @return 处理后的数据
     * @throws Exception 处理失败时抛出异常
     */
    private static byte[] doFinalWithBlock(Cipher cipher, byte[] data, int maxBlock) throws Exception {
        int inputLen = data.length;
        java.io.ByteArrayOutputStream out = new java.io.ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;

        // 分段解密
        while (inputLen - offset > 0) {
            if (inputLen - offset > maxBlock) {
                cache = cipher.doFinal(data, offset, maxBlock);
            } else {
                cache = cipher.doFinal(data, offset, inputLen - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * maxBlock;
        }

        byte[] result = out.toByteArray();
        out.close();
        return result;
    }

    /**
     * 测试方法
     */
    public static void main(String[] args) {
        try {
            // 示例：解密从API获取的加密会员码
            String encryptedCode = "这里填入从 /v1/memberCard/code 接口获取的加密数据";

            // 调用解密方法
            String decryptedCode = decryptData(encryptedCode);

            System.out.println("加密数据: " + encryptedCode);
            System.out.println("解密结果: " + decryptedCode);

        } catch (Exception e) {
            System.err.println("解密失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}


